package com.ruoyi.basic.controller;

import java.io.IOException;
import java.util.*;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.basic.entity.Fwgl;
import com.ruoyi.basic.service.IFwglService;
import com.ruoyi.common.entity.Enginemapfile;
import com.ruoyi.common.service.IAttachmentsListService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.entity.AttachmentsList;
import com.ruoyi.common.service.IEnginemapfileService;
import com.ruoyi.common.util.LockDocUtils;
import com.ruoyi.common.util.Tools;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.flowable.services.ProcessEngineService;
import com.ruoyi.framework.web.service.TokenService;
import org.flowable.bpmn.model.CustomProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping("/fwgl/form")
public class FwglController extends BaseController {

    @Autowired
    private IFwglService fwglService;
    @Autowired
    private IAttachmentsListService attachmentsListService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ProcessEngineService processEngineService;
    @Autowired
    private LockDocUtils lockDocUtils;
    @Autowired
    private IEnginemapfileService enginemapfileService;
    /**
     * 查询【发文管理】列表
     */
    @GetMapping("/list")
    public TableDataInfo list(Fwgl fwgl)
    {
        startPage();
        List<Fwgl> list = fwglService.selectFwglList(fwgl);
        return getDataTable(list);
    }

    /**
     * 导出【发文管理】列表
     */
    @Log(title = "【发文管理表单【获取详细信息】】", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(Fwgl fwgl)
    {
        List<Fwgl> list = fwglService.selectFwglList(fwgl);
        ExcelUtil<Fwgl> util = new ExcelUtil<Fwgl>(Fwgl.class);
        return util.exportExcel(list, "fwgl");
    }

    /**
     * 获取【发文管理】详细信息
     */
    @GetMapping(value = "/{docunid}")
    public AjaxResult getInfo(@PathVariable("docunid") String docunid)
    {
        return AjaxResult.success(fwglService.selectFwglById(docunid));
    }

    /**
     * 保存【发文管理】业务数据
     */
    @Log(title = "发文管理表单【保存】", businessType = BusinessType.INSERT)
    @PostMapping("/save")
    public AjaxResult add(@RequestBody Map<String, JSONObject> data,HttpServletRequest request)
    {

        System.out.println("-----");
        System.out.println(data.get("submitData"));
        System.out.println("-----");
        JSONObject fwglJson = data.get("formData");
        JSONObject submitJson = data.get("submitData");
        Fwgl fwgl = JSONObject.toJavaObject(fwglJson,Fwgl.class);
        if(fwgl.getDocunid() == null){
            fwgl.setDocunid(Tools.createUUID());
        }
        Map<String, Object> map = parsingSubmitFormData(submitJson);
        System.out.println("------");
        System.out.println(fwgl.toString());
        int insertNum=0;
        Fwgl oldFwgl = fwglService.selectFwglById(fwgl.getDocunid());
        if (oldFwgl == null){
            //没有记录就说明是新增记录
            insertNum = fwglService.insertFwgl(fwgl);
        }else {
            //有记录就进行更新操作
            insertNum = fwglService.updateFwgl(fwgl);
        }
        //业务数据保存成功，并且流程实例表中没有数据,则启动流程
        if( insertNum > 0 ){
            String currentUser=String.valueOf(tokenService.getLoginUser(request).getUser().getUserId());
            String instanceid = processEngineService.postSubmit(fwgl.getProcessDefinitionKey(),submitJson.getString("userTaskId"),map,currentUser);
            System.out.println("instanceid======"+instanceid);
            //插入新记录到流程实例映射表--enginemapfile表
            if(StringUtils.isNotEmpty(instanceid)&& (enginemapfileService.selectEnginemapfileByDocUnid(fwgl.getDocunid())==null)){
                Enginemapfile enginemapfile = new Enginemapfile();
                enginemapfile.setId(Tools.createUUID());
                enginemapfile.setDocunid(fwgl.getDocunid());
                enginemapfile.setInstanceid(instanceid);
                enginemapfileService.insertEnginemapfile(enginemapfile);
            }
        }
        /*//测试
        SysUser user = tokenService.getLoginUser(request).getUser();
        Map<String, Object> returnMap = lockDocUtils.checkIsLocked(docUnid, user);
        System.out.println("文档是否被锁："+returnMap.toString());
        Boolean lock = lockDocTools.lockDoc(docUnid,user);
        System.out.println("文档是否锁定成功："+lock);
        Boolean unlock = lockDocTools.unlockDocs(docUnid,user);
        System.out.println("文档是否解锁成功："+unlock);*/
        return toAjax(insertNum);
    }

    /**
     * 解析sumitformJSON，因具体业务不同，可能存在一些其他控制变量，产生流程提交的临时变量
     * @param submitJson
     * @return map：processMap参数
     */
    private Map<String,Object> parsingSubmitFormData(JSONObject submitJson){
        //map是全量对象，需要解析成流程需要的对象
        Map<String, Object> map=new HashMap<>();
        //ProcessSubmitRemark  用户提交意见
        String ProcessSubmitRemark=submitJson.getString("ProcessSubmitRemark");
        //从提交参数中获取路由选择，并解析获取路由条件参数及变量使流程提交唯一性
        String router=submitJson.getString("user_select_router");
        map.put("selectedFlow",router);

        //获取下一环节,并设置流程提交变量
        JSONArray nextUserTasks=submitJson.getJSONArray("selectedUsers");
        List<String> nextUserArray = new ArrayList<String>();
        String nodeid = "";
        for (int x=0;x<nextUserTasks.size();x++){
            JSONObject nextUserTask=nextUserTasks.getJSONObject(x);
            JSONArray selectUserArray = nextUserTask.getJSONArray("selectedUser");
            for(int i =0;i<selectUserArray.size();i++){
                JSONObject nextUser=selectUserArray.getJSONObject(i);
                nextUserArray.add(nextUser.getString("userName"));
                nodeid = nextUserTask.getString("userTaskId");
                map.put(nextUserTask.getString("userTaskId")+"_assignees",nextUser.getString("userName"));
            }
        }
        if(nextUserArray.size()>1){
            map.put(nodeid+"_collection",nextUserArray);
        }
        //以下写业务数据变量



        return map;
    }

    /**
     * 修改【发文管理】
     */
    @Log(title = "【发文管理表单【修改】】", businessType = BusinessType.UPDATE)
    @PutMapping("/edit")
    public AjaxResult edit(@RequestBody Fwgl fwgl)
    {
        return toAjax(fwglService.updateFwgl(fwgl));
    }

    /**
     * 删除【发文管理】
     */
    @Log(title = "【发文管理表单【删除】】", businessType = BusinessType.DELETE)
    @DeleteMapping("/{docunids}")
    public AjaxResult remove(@PathVariable String[] docunids)
    {
        return toAjax(fwglService.deleteFwglByIds(docunids));
    }

    /**
     * 打开表单前进行表单类型判断
     */
    @GetMapping("/judgeDocType")
    public AjaxResult judgeDocType(@RequestParam String docUnid,@RequestParam(required = false) String taskId,HttpServletRequest request){
        //获取请求用户对象
        SysUser logUser = tokenService.getLoginUser(request).getUser();
        JSONObject reDataJson = new JSONObject();
        //如果taskId不为空就代表是待办
        if(StringUtils.isNotEmpty(taskId)){
            //判断能否找到表单信息
            if(enginemapfileService.selectEnginemapfileByDocUnid(docUnid) != null
                    && fwglService.selectFwglById(docUnid) !=null
                        ){
                //返回 打开待办表单
                List<CustomProperty> listpops = processEngineService.getCurrentCustomPropsByTaskId(taskId);
                reDataJson.put("openDocType","todo");
                return new AjaxResult(0,"查询成功",reDataJson);
            }else{
                //如果不是返回错误信息
                reDataJson.put("openDocType","error");
                return new AjaxResult(-1,"无权限处理",reDataJson);
            }
        }else{
            //如果不为空就代表是已办or已申请or草稿箱
            Fwgl fwgl = fwglService.selectFwglById(docUnid);
            if(fwgl == null ){
                //找不到业务实体则直接返回错误信息
                reDataJson.put("openDocType","error");
                return new AjaxResult(-1,"无权限处理",reDataJson);
            }
            Enginemapfile enginemapfile = enginemapfileService.selectEnginemapfileByDocUnid(docUnid);
            //如果找不倒流程实例id则表明是草稿箱
            if(enginemapfile == null || StringUtils.isEmpty(enginemapfile.getInstanceid())){
                //返回 草稿箱
                reDataJson.put("openDocType","drafts");
                return new AjaxResult(0,"查询成功",reDataJson);
            }else{
               if (Integer.parseInt(fwgl.getWriterid())==logUser.getUserId()){
                   //返回我的申请
                   reDataJson.put("openDocType","apply");
                   return new AjaxResult(0,"查询成功",reDataJson);
               }
               if (1==1){
                   //返回我的已办
                   reDataJson.put("openDocType","havaTodo");
                   return new AjaxResult(0,"查询成功",reDataJson);
               }
               if(1==1){
                   //返回我的待阅
                   reDataJson.put("openDocType","toread");
                   return new AjaxResult(0,"查询成功",reDataJson);
               }
               if(1==1){
                   //返回我的已阅
                   reDataJson.put("openDocType","haveToread");
                   return new AjaxResult(0,"查询成功",reDataJson);
               }
            }
        }
        System.out.println("----"+docUnid+"----");
        System.out.println("----"+taskId+"----");
        reDataJson.put("openDocType","error");
        return new AjaxResult(-1,"系统异常，联系管理员处理",reDataJson);
    }

    /**
     * 上传附件【发文管理】
     */
    @Log(title = "【发文管理表单【上传附件】】", businessType = BusinessType.OTHER)
    @RequestMapping("/upload")
    public String UploadFiles (HttpServletRequest request, MultipartFile file, String docunid){
        try {
            //获取文件名称
            String fileName = file.getOriginalFilename();
            //获取文件后缀名
            String fileExt = FileUploadUtils.getExtension(file);
            //文件保存路径
            String filePath = FileUploadUtils.upload(file);
            //文件大小kb
            String fileSize = (file.getSize() / 1024)+"";
            SysUser loginUser = tokenService.getLoginUser(request).getUser();
            AttachmentsList attachmentsList = new AttachmentsList();
            if(attachmentsList.getId() == null){
                attachmentsList.setId(Tools.createUUID());
            }
            attachmentsList.setAddid(loginUser.getUserId()+"");
            attachmentsList.setAddname(loginUser.getUserName());
            attachmentsList.setDeleteflag("1");
            attachmentsList.setFilename(fileName);
            attachmentsList.setFilepath(filePath);
            attachmentsList.setFilesize(fileSize);
            attachmentsList.setFiletype(fileExt);
            attachmentsList.setAdddate(new Date());
            attachmentsList.setDocunid(docunid);
            attachmentsList.setDeleteflag("0");
            saveAttachmentsList(attachmentsList);
            System.out.println(attachmentsList.toString());
            System.out.println("上传位置==="+filePath);
            return attachmentsList.getId();

        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
    /**
     * 删除附件【发文管理】
     */
    @Log(title = "【发文管理表单【删除附件】】", businessType = BusinessType.OTHER)
    @GetMapping("/removefile/{fileid}")
    public void RemoveFile (@PathVariable("fileid") String fileid){
        System.out.println("fileid === "+fileid);
        AttachmentsList attachmentsList = attachmentsListService.selectAttachmentsListById(fileid);
        if(attachmentsList != null){
            System.out.println(attachmentsList.toString());
            attachmentsList.setDeleteflag("1");
            attachmentsListService.updateAttachmentsList(attachmentsList);
        }
    }
    /**
     * 获取附件列表【发文管理】
     */
    @Log(title = "【获取附件列表【删除附件】】", businessType = BusinessType.OTHER)
    @GetMapping("/getfiles/{docUnid}")
    public TableDataInfo getFilesByDocUnid (@PathVariable("docUnid") String docUnid){
        System.out.println("docUnid === "+docUnid);
        List<AttachmentsList> attachmentsListSet = attachmentsListService.selectAttachmentsListByDocUnid(docUnid);
        return getDataTable(attachmentsListSet);
    }
    private int saveAttachmentsList(AttachmentsList attachmentsList){
        return attachmentsListService.insertAttachmentsList(attachmentsList);
    }
}
